package com.yunhe.authority.repository.company.dao;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yunhe.authority.domain.office.Office;
import com.yunhe.authority.domain.company.Company;
import com.yunhe.authority.model.CompanyUpload;
import com.yunhe.authority.repository.company.CompanyRepository;
import com.yunhe.common.model.PageParam;
import com.yunhe.common.util.StringUtil;
import org.neo4j.ogm.model.Result;
import org.neo4j.ogm.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
import com.yunhe.common.util.CollectionUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 设备数据仓库自定义实现
 * @author liuronglei
 */
@Repository
public class CompanyRepositoryImpl implements CompanyRepository {
    @Autowired
    private Session session;

    private List<Company> getCompanyList(Result results) {
        List<Company> list = new ArrayList<>();
        for (Map<String, Object> result : results) {
            Company company = new Company();
            Map<String, Object> object = (Map<String, Object>) result.get("company");
            company.setId(Long.parseLong(String.valueOf(object.get("id"))));
            company.setCode(Long.parseLong(String.valueOf(object.get("code"))));
            company.setTitle((String) object.get("title"));
            company.setName((String) object.get("name"));
            company.setAbbreviation((String) object.get("abbreviation"));
            company.setSn((String) object.get("sn"));
            company.setArea((double) object.get("area"));
            company.setLeaseTime((String) object.get("leaseTime"));
            company.setLeaseDueTime((String) object.get("leaseDueTime"));
            company.setLegalPerson((String) object.get("legalPerson"));
            company.setChargePerson((String) object.get("chargePerson"));
            String staffCount = (String) object.get("staffCount");
            String starGrade = (String) object.get("starGradeInt");
            String annualOutputValue = (String) object.get("annualOutputValue");
            String solvingEmploymentNum = (String) object.get("solvingEmploymentNum");
            String taxes = (String) object.get("taxes");
            String totalOutputValue = (String) object.get("totalOutputValue");
            company.setOffices((List<Office>) object.get("offices"));
            list.add(company);
        }
        return list;
    }

    private Company getCompany(Result result) {
        List<Company> companys = getCompanyList(result);
        if (companys != null && companys.size() > 0) {
            return companys.get(0);
        }
        return null;
    }

    /**
     * 根据ID获得企业
     *
     * @param companyId 企业ID
     */
    @Override
    public Company findById(Long companyId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("companyId", companyId);
        String cypher = "match(c:Company) where id(c)={companyId} return c";
        Company result = session.queryForObject(Company.class, cypher, paramMap);
        return result;
    }

    /**
     * 根据单位ID获得企业对象列表
     *
     * @param firmId 单位ID
     */
    @Override
    public List<Company> findByFirmId(Long firmId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("firmId", firmId);
        String cypher = "start f=node({firmId}) match(f)-[:HAS_STATION]->(s:Station)-[:HAS_RESOURCE{type:'Company'}]->(company:Company{activity:true})" +
                "  return company{id:id(company),.*}";
        Iterable<Company> result = session.query(Company.class, cypher, paramMap);
        return (List<Company>)result;
    }

    /**
     * 根据电站ID获得所有企业列表
     *
     * @param stationId 电站ID
     */
    @Override
    public List<Company> findByStationId(Long stationId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("stationId", stationId);
        String cypher = "start s=node({stationId}) match(s)-[:HAS_RESOURCE{type:'Company'}]->(company:Company)" +
                "  return company{id:id(company),.*}";
        //"start s=node({stationId}) match(s)-[:HAS_RESOURCE{type:'Company'}]->(company:Company{activity:true})" +
        //                "  return company{id:id(company),.*}";
        Iterable<Company> result = session.query(Company.class, cypher, paramMap);
        return (List<Company>)result;
    }

    @Override
    public List<Company> findByRealStationId(Long realStationId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("id", realStationId);
        String cypher = "start realStation=node({id}) match(realStation)-[:HAS_COMPANIES{id:{id}}]->(company:Company)" +
                "  return company{id:id(company),.*}";

        Iterable<Company> result = session.query(Company.class, cypher, paramMap);
        return (List<Company>)result;
    }

    /**
     * 获得所有企业
     */
    @Override
    public List<Company> findAll() {
        Map<String, Object> paramMap = new HashMap<>();
        String cypher = "match(company:Company{activity:true}) return company{id:id(company),.*}";
        Iterable<Company> result = session.query(Company.class, cypher, paramMap);
        return (List<Company>)result;
    }

    @Override
    public List<Company> unbindAllOffice(Long id) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("id", id);
        String cypher = "match (n:Company)-[r:HAS_OFFICE]->(o:Office) where ID(n)={id} delete r";
        Result result = session.query(cypher, paramMap);
        return new ArrayList<>();
    }

    @Override
    public Page<CompanyUpload> findAllForPage(PageParam pageParam) {
        StringBuffer cql = new StringBuffer();
        //拼接基本语句
        cql.append("match (n:Company)-[r:HAS_OFFICE]->(o:Office) WHERE 1=1");
        //拼接返回值和Limit部分
        int skip = (pageParam.getPage() - 1) * pageParam.getSize();
        String queryEnd = " RETURN ID(o) as id ,n.name as name , n.stationTitle as stationTitle , o.officeName as buildingNumber, " +
                "o.officeArea as area ,o.leaseTime as leaseTime , o.leasePrice as leasePrice ,o.leaseDueTime as leaseDueTime ," +
                "n.legalPerson as legalPerson,n.chargePerson as chargePerson ,n.investment as investment , " +
                "n.product as product,n.staffCount as staffCount,n.averageIncome as averageIncome,n.investor as investor," +
                "n.idNumber as idNumber,n.electricityLoad as electricityLoad ,n.substationNo as substationNo," +
                "n.annualWaterConsumption as annualWaterConsumption ,n.monthlyWaterConsumption as monthlyWaterConsumption," +
                "n.annualElectricityConsumption as annualElectricityConsumption , n.monthlyElectricityConsumption as monthlyElectricityConsumption," +
                "n.starGrade as starGrade , n.unifiedSocialCreditCode as unifiedSocialCreditCode , n.taxpayerIdentificationNumber as taxpayerIdentificationNumber," +
                "n.businessRegistrationNumber as businessRegistrationNumber , n.organizationCode as organizationCode order by o.leaseTime desc SKIP " + skip + " LIMIT " + pageParam.getSize();
        String countEnd = " RETURN count(o)";


        //分页数据查询结果
        Result result = session.query(cql.toString() + queryEnd, Maps.newHashMap());
        //查询总数
        Integer total = session.queryForObject(Integer.class, cql.toString() + countEnd, Maps.newHashMap());
        //封装为分页类
        List<CompanyUpload> users = new ArrayList<>();
        if (result != null) {
            for (Map<String, Object> map : result) {
                CompanyUpload projectUser = JSONObject.parseObject(JSONObject.toJSONString(map), CompanyUpload.class);
                users.add(projectUser);
            }
        }
        Page<CompanyUpload> page = null;
        if (!CollectionUtil.isEmpty(users)) {
            List<CompanyUpload> content = Lists.newArrayList(users);
            Pageable pageable = PageRequest.of(pageParam.getPage() - 1, pageParam.getSize());
            page = new PageImpl<CompanyUpload>(content, pageable, total);
        }
        return page;
    }

    @Override
    public Page<Company> findCompaniesByStationId(String searchKey, Long id, PageParam pageParam) {
        StringBuffer cql = new StringBuffer();
        //拼接基本语句
        cql.append("match(s:Station)<-[:BELONG_TO_STATION{stationId:" + id + "}]-(rt:RealStation)-[r:HAS_COMPANIES{realStationId:id(rt)}]->(c:Company) ");

        //按姓名模糊查询
        if (!StringUtil.isEmpty(searchKey)) {
            cql.append(" where c.title=~ '.*" + searchKey + ".*' ");
        }

        //拼接返回值和Limit部分
        int skip = (pageParam.getPage() - 1) * pageParam.getSize();
        String queryEnd = " RETURN c SKIP " + skip + " LIMIT " + pageParam.getSize();
        String countEnd = " RETURN count(c)";

        //分页数据查询结果
        Iterable<Company> companies = session.query(Company.class, cql.toString() + queryEnd, Maps.newHashMap());
        //查询总数
        Integer total = session.queryForObject(Integer.class, cql.toString() + countEnd, Maps.newHashMap());

        //封装为分页类
        List<Company> content = Lists.newArrayList(companies);
        Pageable pageable = PageRequest.of(pageParam.getPage() - 1, pageParam.getSize());
        Page<Company> page = new PageImpl<Company>(content, pageable, total);
        return page;
    }

    @Override
    public Page<Company> findCompaniesByRealStationId(String searchKey, Long id, PageParam pageParam) {
        StringBuffer cql = new StringBuffer();
        //拼接基本语句
        cql.append("match(rt:RealStation)-[r:HAS_COMPANIES{realStationId:" +id +"}]->(c:Company) ");

        //按姓名模糊查询
        if (!StringUtil.isEmpty(searchKey)) {
            cql.append(" where c.title=~ '.*" + searchKey + ".*' ");
        }

        //拼接返回值和Limit部分
        int skip = (pageParam.getPage() - 1) * pageParam.getSize();
        String queryEnd = " RETURN c SKIP " + skip + " LIMIT " + pageParam.getSize();
        String countEnd = " RETURN count(c)";

        //分页数据查询结果
        Iterable<Company> companies = session.query(Company.class, cql.toString() + queryEnd, Maps.newHashMap());
        //查询总数
        Integer total = session.queryForObject(Integer.class, cql.toString() + countEnd, Maps.newHashMap());

        //封装为分页类
        List<Company> content = Lists.newArrayList(companies);
        Pageable pageable = PageRequest.of(pageParam.getPage() - 1, pageParam.getSize());
        Page<Company> page = new PageImpl<Company>(content, pageable, total);
        return page;
    }

    @Override
    public Iterable<Company> findListCompaniesByRealStationId(Long id) {
        StringBuffer cql = new StringBuffer();
        //拼接基本语句
        cql.append("match(rt:RealStation)-[r:HAS_COMPANIES{realStationId:" +id +"}]->(c:Company) RETURN c");

        //查询结果
        Iterable<Company> companies = session.query(Company.class, cql.toString(), Maps.newHashMap());

        return companies;
    }
}
